package liveSimBE;

public abstract class Simulator extends Thread {
  abstract void step(long stepNum, int nSteps);
  
  /**
   * Number of time steps per second.
   */
  double rate;
  
  long startTime;
  long stepNum;
  long nsPerStep;
    
  public final long nextStepTime() {
    return startTime + stepNum * nsPerStep;
  }
  
  public void run() {
    startTime = System.nanoTime();
    stepNum = 0;
    nsPerStep = (long) (1e9/rate);
    while(true) {
      // Do a step if we're ready.
      long diff;
      while ((diff = nextStepTime() - System.nanoTime()) <= 0) {
        long todo = (-diff / nsPerStep) + 1;
        // Do a step.
        step(stepNum, (int)todo);
        stepNum += todo;
      }

      // Sleep.
      try {
        sleep(diff / 1000000, (int) (diff % 1000000));
      } catch (InterruptedException e) {
        // Do nothing; we'll catch it on the next time through the loop.
      }
    }
  }
  
  public static void main(String[] args) {
    Simulator sim = new TestSimulation();
    sim.start();
  }
}
